package pers.yurwisher.rubick.common.utils;

import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.cache.Cache;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.http.MediaType;
import pers.yurwisher.rubick.common.serializer.CustomGenericFastJsonRedisSerializer;

import java.time.LocalDateTime;
import java.util.ArrayList;

/**
 * @author yq 2021/4/21 17:17
 * @description ObjectHelper 常用对象持有
 */
@Slf4j
public class ObjectHelper {


    public static MetaObjectHandler getDefaultMetaObjectHandler() {
        return new MetaObjectHandler() {
            @Override
            public void insertFill(MetaObject metaObject) {
                this.setFieldValByName("enabled", true, metaObject);
                this.setFieldValByName("dateCreated", LocalDateTime.now(), metaObject);
                this.setFieldValByName("lastUpdated", LocalDateTime.now(), metaObject);
            }

            @Override
            public void updateFill(MetaObject metaObject) {
                this.setFieldValByName("lastUpdated", LocalDateTime.now(), metaObject);
            }
        };
    }

    public static CacheErrorHandler getDefaultRedisCacheErrorHandler() {
        return new CacheErrorHandler() {

            @Override
            public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
                log.error("Redis occur handleCacheGetError：key -> [{}]", key, e);
            }

            @Override
            public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
                log.error("Redis occur handleCachePutError：key -> [{}]；value -> [{}]", key, value, e);
            }

            @Override
            public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
                log.error("Redis occur handleCacheEvictError：key -> [{}]", key, e);
            }

            @Override
            public void handleCacheClearError(RuntimeException e, Cache cache) {
                log.error("Redis occur handleCacheClearError：", e);
            }

        };
    }

    public static FastJsonHttpMessageConverter getDefaultFastJsonHttpMessageConverter() {
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        //不可使用*/*,强制用户自己定义支持的MediaTypes
        fastConverter.setSupportedMediaTypes(new ArrayList<MediaType>() {
            private static final long serialVersionUID = 2644645137309978808L;

            {
                add(MediaType.APPLICATION_JSON);
                add(MediaType.TEXT_PLAIN);
            }
        });
        //全局配置
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                //是否输出值为null的字段,默认false
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullListAsEmpty,
                //全局修改日期格式,默认false,格式为 yyyy-MM-dd
                SerializerFeature.WriteDateUseDateFormat,
                //字符串输出null值
                SerializerFeature.WriteNullStringAsEmpty
        );
        //整型转字符串 防止前端精度丢失
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(Long.class, ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
        fastJsonConfig.setSerializeConfig(serializeConfig);
        //全局日期格式
        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
        fastConverter.setFastJsonConfig(fastJsonConfig);
        return fastConverter;
    }

    public static RedisTemplate<String, Object> getDefaultRedisTemplate(RedisConnectionFactory connectionFactory){
        return getDefaultRedisTemplate(connectionFactory,new CustomGenericFastJsonRedisSerializer());
    }

    public static RedisTemplate<String, Object> getDefaultRedisTemplate(RedisConnectionFactory connectionFactory,CustomGenericFastJsonRedisSerializer fastJsonRedisSerializer){
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // value值的序列化采用fastJsonRedisSerializer
        template.setValueSerializer(fastJsonRedisSerializer);
        template.setHashValueSerializer(fastJsonRedisSerializer);
        // key的序列化采用StringRedisSerializer
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);

        template.setDefaultSerializer(fastJsonRedisSerializer);
        template.setConnectionFactory(connectionFactory);
        template.afterPropertiesSet();
        return template;
    }

}
